package com.godenwater.recv.spring;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

public class Configurer extends PropertyPlaceholderConfigurer {
	private static Map<String, Object> ctxPropertiesMap;

	protected void processProperties(
			ConfigurableListableBeanFactory beanFactoryToProcess,
			Properties props) throws BeansException {
		super.processProperties(beanFactoryToProcess, props);
		ctxPropertiesMap = new HashMap<String, Object>();
		for (Object key : props.keySet()) {
			String keyStr = key.toString();
			String value = props.getProperty(keyStr);
			ctxPropertiesMap.put(keyStr, value);
		}
	}

	public static Object getContextProperty(String name) {
		//System.out.println(">> ctxPropertiesMap "+ ctxPropertiesMap);
		return ctxPropertiesMap.get(name);
	}

	public static Map<String, Object> getProperties() {
		return ctxPropertiesMap;
	}
	
	public static String getProperty(String name) {
		return getStringProperty(name, "");
	}

	public static void setProperty(String name, String value) {
		ctxPropertiesMap.put(name, value);
	}

	/**
	 * Get the trimmed String value of the property with the given
	 * <code>name</code>. If the value the empty String (after trimming), then
	 * it returns null.
	 */
	public static String getStringProperty(String name) {
		return getStringProperty(name, null);
	}

	/**
	 * Get the trimmed String value of the property with the given
	 * <code>name</code> or the given default value if the value is null or
	 * empty after trimming.
	 */
	public static String getStringProperty(String name, String def) {
		String val = (String) Configurer.getContextProperty(name);
		// String val = props.getProperty(name, def);
		if (val == null) {
			return def;
		}

		val = val.trim();

		return (val.length() == 0) ? def : val;
	}

	public static String[] getStringArrayProperty(String name) {
		return getStringArrayProperty(name, null);
	}

	public static String[] getStringArrayProperty(String name, String[] def) {
		String vals = getStringProperty(name);
		if (vals == null) {
			return def;
		}

		StringTokenizer stok = new StringTokenizer(vals, ",");
		ArrayList<String> strs = new ArrayList<String>();
		try {
			while (stok.hasMoreTokens()) {
				strs.add(stok.nextToken().trim());
			}

			return (String[]) strs.toArray(new String[strs.size()]);
		} catch (Exception e) {
			return def;
		}
	}

	public static boolean getBooleanProperty(String name) {
		return getBooleanProperty(name, false);
	}

	public static boolean getBooleanProperty(String name, boolean def) {
		String val = getStringProperty(name);

		return (val == null) ? def : Boolean.valueOf(val).booleanValue();
	}

	public static byte getByteProperty(String name)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Byte.parseByte(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static byte getByteProperty(String name, byte def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Byte.parseByte(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static char getCharProperty(String name) {
		return getCharProperty(name, '\0');
	}

	public static char getCharProperty(String name, char def) {
		String param = getStringProperty(name);
		return (param == null) ? def : param.charAt(0);
	}

	public static double getDoubleProperty(String name)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Double.parseDouble(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static double getDoubleProperty(String name, double def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Double.parseDouble(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static float getFloatProperty(String name)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Float.parseFloat(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static float getFloatProperty(String name, float def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Float.parseFloat(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static int getIntProperty(String name) throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Integer.parseInt(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static int getIntProperty(String name, int def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Integer.parseInt(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static int[] getIntArrayProperty(String name)
			throws NumberFormatException {
		return getIntArrayProperty(name, null);
	}

	public static int[] getIntArrayProperty(String name, int[] def)
			throws NumberFormatException {
		String vals = getStringProperty(name);
		if (vals == null) {
			return def;
		}

		StringTokenizer stok = new StringTokenizer(vals, ",");
		ArrayList<Integer> ints = new ArrayList<Integer>();
		try {
			while (stok.hasMoreTokens()) {
				try {
					ints.add(new Integer(stok.nextToken().trim()));
				} catch (NumberFormatException nfe) {
					throw new NumberFormatException(" '" + vals + "'");
				}
			}

			int[] outInts = new int[ints.size()];
			for (int i = 0; i < ints.size(); i++) {
				outInts[i] = ((Integer) ints.get(i)).intValue();
			}
			return outInts;
		} catch (Exception e) {
			return def;
		}
	}

	public static long getLongProperty(String name)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Long.parseLong(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static long getLongProperty(String name, long def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Long.parseLong(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static short getShortProperty(String name)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			throw new NumberFormatException(" null string");
		}

		try {
			return Short.parseShort(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

	public static short getShortProperty(String name, short def)
			throws NumberFormatException {
		String val = getStringProperty(name);
		if (val == null) {
			return def;
		}

		try {
			return Short.parseShort(val);
		} catch (NumberFormatException nfe) {
			throw new NumberFormatException(" '" + val + "'");
		}
	}

}
